package com.run.gogo.action;

import com.run.gogo.context.NodeContext;
import com.run.gogo.context.NodeMessage;
import com.run.gogo.node.Node;
import com.run.gogo.util.NodeActionUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.concurrent.CompletableFuture;

/**
 * 异步处理
 * */
public class AsycNodeAction implements NodeAction{
    private static final Log log = LogFactory.getLog(AsycNodeAction.class);
    private Node innerNode;
    private String name;

    /**
     * 回调
     * */
    private AsycNodeListener asycNodeListener;

    public AsycNodeAction(String name,String listenerClassName,String listenerSpringBeanName,Node innerNode){
        this.name = name;
        this.innerNode = innerNode;

        if(StringUtils.isNotEmpty(listenerClassName)){
            this.asycNodeListener = NodeActionUtil.getAsycNodeListenerByClass(listenerClassName);
        }
        if(StringUtils.isNotEmpty(listenerSpringBeanName)){
            this.asycNodeListener = NodeActionUtil.getAsycNodeListenerBySpring(listenerSpringBeanName);
        }
    }


    @Override
    public void action(NodeContext nodeContext) {

        /**
         * 创建一个新的对象
         * */
        NodeMessage newMsg = new NodeMessage();
        newMsg.putAll(nodeContext.getIn());
        NodeContext newNodeContext = new NodeContext(newMsg);
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                log.info(String.format("%s-异步处理开始",name));
                try {
                    innerNode.action(newNodeContext);
                    if(null!=asycNodeListener){
                        CompletableFuture.runAsync(new Runnable() {
                            @Override
                            public void run() {
                                asycNodeListener.complete(nodeContext);
                            }
                        });
                    }
                }catch (Throwable te){
                    log.error(String.format("%s-异步处理异常",name),te);
                    if(null!=asycNodeListener){
                        CompletableFuture.runAsync(new Runnable() {
                            @Override
                            public void run() {
                                asycNodeListener.fail(nodeContext,te);
                            }
                        });
                    }
                }
                log.info(String.format("%s-异步处理结束",name));
            }
        });
    }

}
